package com.scs.application.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.modules.dept.service.ApplyAutoHistoryService;
import com.scs.application.modules.dept.service.ApplyAutoService;
import com.scs.application.modules.finance.service.BillItemService;
import com.scs.application.modules.purchase.service.OrderItemService;
import com.scs.application.modules.sys.entity.Appraise;
import com.scs.application.modules.sys.entity.AppraiseStandard;
import com.scs.application.modules.sys.mapper.AppraiseMapper;
import com.scs.application.modules.sys.service.AppraiseService;
import com.scs.application.modules.sys.service.AppraiseStandardService;
import com.scs.application.modules.wm.entity.Stock;
import com.scs.application.modules.wm.entity.StockHistory;
import com.scs.application.modules.wm.service.StockHistoryService;
import com.scs.application.modules.wm.service.StockService;
import com.scs.application.modules.wm.service.WorkOrderItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Service
public class AppraiseServiceImpl extends BaseServiceImpl<AppraiseMapper, Appraise> implements AppraiseService {

    @Autowired
    private BillItemService billItemService;

    @Autowired
    private StockHistoryService stockHistoryService;

    @Autowired
    private StockService stockService;

    @Autowired
    private ApplyAutoService applyAutoService;

    @Autowired
    private ApplyAutoHistoryService applyAutoHistoryService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private WorkOrderItemService workOrderItemService;


    @Autowired
    private AppraiseStandardService appraiseStandardService;

    @Override
    public void calculateAppraise() {
        Calendar calendar = Calendar.getInstance();

        //时间格式yyyy-MM-dd
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
        String strDate = sdfDate.format(calendar.getTime());

        Appraise existedAppraise = this.getOne(Wrappers.<Appraise>query().eq("bus_date", strDate).last("limit 1"));

        Appraise appraise = new Appraise();
        appraise.setBusDate(calendar.getTime()).setRotationRate(getRotationRate()).setChoiceRate(getChoiceRate())
                .setPurchaseRate(getPurchaseRate());
        appraise.setTurnoverDays(getTurnOverDays(appraise.getRotationRate()));

        Appraise lastAppraise = this.getOne(Wrappers.<Appraise>query().orderByDesc("gmt_modified").last("limit 1"));

        if (lastAppraise != null) { //根据上一条获取百分比
            appraise.setRotationPercent(lastAppraise.getRotationPercent())
                    .setChoicePercent(lastAppraise.getChoicePercent())
                    .setPurchasePercent(lastAppraise.getPurchasePercent());
        } else {
            appraise.setRotationPercent(35d)
                    .setChoicePercent(35d)
                    .setPurchasePercent(30d);
        }

        List<AppraiseStandard> appraiseStandards = appraiseStandardService.list();

        AppraiseStandard rotateRateStandard = appraiseStandards.stream().filter(stand ->
                GlobalConsts.APPRAISE_TYPE_ROTATE_RATE.equalsIgnoreCase(stand.getAppraiseType()) &&
                        appraise.getRotationRate() > stand.getAppraiseLow() &&
                        appraise.getRotationRate() <= stand.getAppraiseHigh()
        ).findAny().orElse(null);

        if (rotateRateStandard != null) {
            appraise.setRotationRateScore(rotateRateStandard.getScore());
        } else {
            appraise.setRotationRateScore(85d); //默认85分
        }

        AppraiseStandard choiceRateStandard = appraiseStandards.stream().filter(stand ->
                GlobalConsts.APPRAISE_TYPE_CHOICE_RATE.equalsIgnoreCase(stand.getAppraiseType()) &&
                        appraise.getChoiceRate() > stand.getAppraiseLow() &&
                        appraise.getChoiceRate() <= stand.getAppraiseHigh()
        ).findAny().orElse(null);

        if (choiceRateStandard != null) {
            appraise.setChoiceRateScore(choiceRateStandard.getScore());
        } else {
            appraise.setChoiceRateScore(85d); //默认85分
        }

        AppraiseStandard purchaseRateStandard = appraiseStandards.stream().filter(stand ->
                GlobalConsts.APPRAISE_TYPE_PURCHASE_RATE.equalsIgnoreCase(stand.getAppraiseType()) &&
                        appraise.getPurchaseRate() > stand.getAppraiseLow() &&
                        appraise.getPurchaseRate() <= stand.getAppraiseHigh()
        ).findAny().orElse(null);

        if (purchaseRateStandard != null) {
            appraise.setPurchaseRateScore(purchaseRateStandard.getScore());
        } else {
            appraise.setPurchaseRateScore(85d); //默认85分
        }

        appraise.setScore((appraise.getRotationRateScore() * appraise.getRotationPercent()
                + appraise.getChoiceRateScore() * appraise.getChoicePercent()
                + appraise.getPurchaseRateScore() * appraise.getPurchasePercent()) / 100);

        if (existedAppraise != null) {
            appraise.setId(existedAppraise.getId());
        }
        this.saveOrUpdate(appraise);
    }

    /**
     * 获取总周转率
     * 计算公式： 消耗量/(期初+期末)/2
     */
    private Double getRotationRate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        //时间格式yyyy-MM-dd
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
        String strDateBegin = sdfDate.format(DateUtils.getFirstDayOfMonth(calendar.getTime()));

//        //期初库存
//        Object objStockBeginQty = stockHistoryService.getObj(Wrappers.<StockHistory>query().eq("back_date", strDateBegin).select("sum(sku_qty)"), v -> v.toString());
//        Double stockBeginQty = Double.valueOf(objStockBeginQty == null ? "0" : objStockBeginQty.toString()); //期初库存
//
//        //期末库存----当前库存
//        Object objStockEndQty = stockService.getObj(Wrappers.<Stock>query().select("sum(sku_qty)"), v -> v.toString());
//        Double stockEndQty = Double.valueOf(objStockEndQty == null ? "0" : objStockEndQty.toString()); //期末库存
//
//        if (stockBeginQty < stockEndQty / 10) {
//            stockBeginQty = stockEndQty;
//        }
//        //总消耗量
//        Double wholeBillQty = getWholeBillQty(false);
//
//        Double rotateRate = wholeBillQty * 2 / (stockBeginQty + stockEndQty);

        //期初金额
        Object objStockBeginAmount = stockHistoryService.getObj(Wrappers.<StockHistory>query().eq("back_date", strDateBegin).select("sum(amount)"), v -> v.toString());
        Double stockBeginAmount = Double.valueOf(objStockBeginAmount == null ? "0" : objStockBeginAmount.toString()); //期初金额

        //期末金额
        Object objStockEndAmount = stockService.getObj(Wrappers.<Stock>query().select("sum(amount)"), v -> v.toString());
        Double stockEndAmount = Double.valueOf(objStockEndAmount == null ? "0" : objStockEndAmount.toString()); //期末金额

        //总消耗量
        Double wholeBillAmount = getWholeBillAmount(false);

        Double rotateRate = wholeBillAmount * 2 / (stockBeginAmount + stockEndAmount);
        return rotateRate;
    }

    /**
     * 获取周期内总消耗量
     * 计算公式： 上一周期到现在总的消耗量
     * Param isYear 是否年度
     */
    private Double getWholeBillQty(Boolean isYear) {
        //时间格式yyyy-MM-dd 00:00:00
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        String strEnd = sdf.format(DateUtils.getLastDayOfMonth(calendar.getTime()));

        Date BeginDate;
        if (isYear) {
            BeginDate = DateUtils.getFirstDayOfYear(calendar.getTime());
        } else {
            BeginDate = DateUtils.getFirstDayOfMonth(calendar.getTime());
        }
        String strBegin = sdf.format(BeginDate);

        return billItemService.getSumSkuQty(strBegin, strEnd); //总消耗数量
    }

    /**
     * 获取周期内总消耗量
     * 计算公式： 上一周期到现在总的消耗量
     * Param isYear 是否年度
     */
    private Double getWholeBillAmount(Boolean isYear) {
        //时间格式yyyy-MM-dd 00:00:00
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        String strEnd = sdf.format(DateUtils.getLastDayOfMonth(calendar.getTime()));

        Date BeginDate;
        if (isYear) {
            BeginDate = DateUtils.getFirstDayOfYear(calendar.getTime());
        } else {
            BeginDate = DateUtils.getFirstDayOfMonth(calendar.getTime());
        }
        String strBegin = sdf.format(BeginDate);

        return billItemService.getSumAmount(strBegin, strEnd); //总消耗金额
    }

    /**
     * 获取平均周转天数
     * 计算公式： 30/库存周转率
     */
    private Double getTurnOverDays(Double rotateRate) {
        if (rotateRate ==null || rotateRate == 0) return 0d;
        return 30 / rotateRate;
    }

    /**
     * 获取备货满足率
     * 计算公式： 消耗数量/请领数量+采购数量 *100%
     */
    private Double getChoiceRate() {
        //时间格式yyyy-MM-dd 00:00:00
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Calendar calendar = Calendar.getInstance();
        String strBegin = sdf.format(DateUtils.getFirstDayOfYear(calendar.getTime()));
        String strEnd = sdf.format(calendar.getTime());
//        Object objApplyQty = applyAutoService.getObj(Wrappers.<ApplyAuto>query().between("gmt_response", strBegin, strEnd)
//                .eq("apply_type", 1).select("sum(sku_qty_stock)"), v -> v.toString());
//
//        Object objApplyHistoryQty = applyAutoHistoryService.getObj(Wrappers.<ApplyAutoHistory>query().between("gmt_complete", strBegin, strEnd)
//                .select("sum(sku_qty_apply)"), v -> v.toString());

//        Object objOrderQty = orderItemService.getObj(Wrappers.<OrderItem>query().between("gmt_create", strBegin, strEnd)
//                .select("sum(sku_qty)"), v -> v.toString());

//        Double applyQty = Double.valueOf(objApplyQty == null ? "0" : objApplyQty.toString()); //科室请领数量
//        Double applyHistoryQty = Double.valueOf(objApplyHistoryQty == null ? "0" : objApplyHistoryQty.toString()); //科室请领历史数量
//        Double orderQty = Double.valueOf(objOrderQty == null ? "0" : objOrderQty.toString()); //采购数量

        Double applyAmount = applyAutoService.getSumAmount(strBegin, strEnd);
        Double applyHistoryAmount = applyAutoHistoryService.getSumAmount(strBegin, strEnd);
                //总消耗量
        Double wholeBillAmount = getWholeBillAmount(true);

        Double choiceRate = wholeBillAmount * 100 / (applyAmount + applyHistoryAmount);
        return  choiceRate;
    }

    /**
     * 获取采购响应率
     * 计算公式： 入库数量/采购数量 * 100%
     */
    private Double getPurchaseRate() {
        //时间格式yyyy-MM-dd 00:00:00
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Calendar calendar = Calendar.getInstance();
        String strBegin = sdf.format(DateUtils.getFirstDayOfYear(calendar.getTime()));
        String strEnd = sdf.format(calendar.getTime());

//        Double orderQty = orderItemService.getSumSkuQty( strBegin, strEnd);//采购数量
//        Double inQty = workOrderItemService.getSumSkuQty( strBegin, strEnd);//入库数量
//
//        Double purchaseRate =  inQty * 100 / orderQty;

        Double orderAmount = orderItemService.getSumAmount( strBegin, strEnd);//采购数量
        Double inAmount = workOrderItemService.getSumAmount( strBegin, strEnd);//入库数量

        Double purchaseRate =  inAmount * 100 / orderAmount;

        return  purchaseRate;
    }
}
